﻿using AutoMapper;
using SqlsugarService.Application.DTOs.PlanDto;
using SqlsugarService.Application.IService.Plan;
using SqlsugarService.Application.Until;
using SqlsugarService.Domain.InventoryChange;
using SqlsugarService.Domain.Materials;
using SqlsugarService.Domain.Plan;
using SqlsugarService.Infrastructure.IRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlsugarService.Domain.BOM;
using SqlsugarService.Domain.Craftsmanship;
using SqlSugar;
using Dm.util;

namespace SqlsugarService.Application.Service.Plan
{
    

    public class ProductionPlanService : IProductionPlanService
    {
        private readonly IBaseRepository<ProductionPlan> baseplan;
        private readonly IBaseRepository<ProductEntity> entitybase;
        private readonly IBaseRepository<Salesorder> orderbase;
        private readonly IBaseRepository<BomItem> bomItemBase;
        private readonly ISqlSugarClient _db;
        private readonly IMapper mapper;

        public ProductionPlanService(
            IBaseRepository<ProductionPlan> baseplan,
            IBaseRepository<ProductEntity> entitybase,
            IBaseRepository<Salesorder> orderbase,
            IBaseRepository<BomItem> bomItemBase,
            ISqlSugarClient db,
            IMapper mapper)
        {
            this.baseplan = baseplan;
            this.entitybase = entitybase;
            this.orderbase = orderbase;
            this.bomItemBase = bomItemBase;
            this._db = db;
            this.mapper = mapper;
        }

        /// <summary>
        /// 新增生产计划
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddProductionPlan(InsertupdateproductionplanDto dto)
        {
            // 参数校验
            if (dto == null)
                return ApiResult.Fail("参数不能为空", ResultCode.Error);

            try
            {
                // 根据当前时间生成唯一编号
                dto.PlanNumber = GenerateProductNumberByTime();
                dto.Id = Guid.NewGuid();
                var res = mapper.Map<InsertupdateproductionplanDto, ProductionPlan>(dto);
                var result = await baseplan.InsertAsync(res);
                return result ? ApiResult.Success(ResultCode.Success) : ApiResult.Fail("新增失败", ResultCode.Error);
            }
            catch (Exception ex)
            {
                // 记录日志（此处省略日志记录逻辑）
                return ApiResult.Fail("系统异常：" + ex.Message, ResultCode.Error);
            }
        }

        /// <summary>
        /// 根据当前时间生成唯一的 ProductNumber，格式为 D + yyyyMMddHHmmss
        /// </summary>
        /// <returns></returns>
        private string GenerateProductNumberByTime()
        {
            var now = DateTime.Now;
            var timePart = now.ToString("yyyyMMddHHmmssfff");
            return $"SCJH{timePart}";
        }

        /// <summary>
        /// 修改生产计划
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> UpdateProductionPlan(InsertupdateproductionplanDto dto)
        {
            var res = mapper.Map<InsertupdateproductionplanDto, ProductionPlan>(dto);
            var result = await baseplan.UpdateAsync(res);
            return result ? ApiResult.Success(ResultCode.Success) : ApiResult.Fail("更新失败", ResultCode.Error);
        }

        /// <summary>
        /// 显示生产计划列表(分页)
        /// </summary>
        /// <param name="seach">分页查询参数</param>
        /// <returns>分页结果</returns>
        public async Task<ApiResult<PageResult<List<GetproductionplanDto>>>> GetProductionPlanList(GetproductionplanSearchDto seach)
        {
            try
            {
                // 获取分页数据
                var pagedList = await baseplan.GetAllAsync();
                if (!string.IsNullOrEmpty(seach.PlanNumber))
                {
                    pagedList = pagedList.Where(x => x.ProductNumber.Contains(seach.PlanNumber) || x.ProductName.Contains(seach.PlanNumber)).ToList();
                }
                if (!string.IsNullOrEmpty(seach.Unit))
                {
                    pagedList = pagedList.Where(x => x.Unit.Contains(seach.Unit)).ToList();
                }
                if (seach.Status != null)
                {
                    pagedList = pagedList.Where(x => x.Status == seach.Status).ToList();
                }
                var totalCount = pagedList.Count();
                var totalPage = (int)Math.Ceiling((double)totalCount / seach.PageSize);
                var res = pagedList.Skip((seach.PageIndex - 1) * seach.PageSize).Take(seach.PageSize).ToList();
                // 映射为DTO
                var mappedList = mapper.Map<List<GetproductionplanDto>>(res);
                // 构建分页结果
                var result = new PageResult<List<GetproductionplanDto>>
                {
                    Data = mappedList,
                    TotalCount = totalCount,
                    TotalPage = totalPage,
                };

                return ApiResult<PageResult<List<GetproductionplanDto>>>.Success(result, ResultCode.Success);
            }
            catch (Exception ex)
            {
                // 记录日志
                return ApiResult<PageResult<List<GetproductionplanDto>>>.Fail($"查询失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 删除生产计划
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResult> DeleteProductionPlan(Guid id)
        {
            var result = await baseplan.SoftDeleteAsync(id);
            return result ? ApiResult.Success(ResultCode.Success) : ApiResult.Fail("删除失败", ResultCode.Error);
        }

        /// <summary>
        /// 为 MES 工具服务提供的异步方法别名 - 获取生产计划列表
        /// </summary>
        /// <param name="seach"></param>
        /// <returns></returns>
        public async Task<ApiResult<PageResult<List<GetproductionplanDto>>>> GetProductionPlanListAsync(GetproductionplanSearchDto seach)
        {
            return await GetProductionPlanList(seach);
        }

        /// <summary>
        /// 为 MES 工具服务提供的异步方法别名 - 新增生产计划
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> InsertProductionPlanAsync(InsertupdateproductionplanDto dto)
        {
            var result = await AddProductionPlan(dto);
            return result.Code == ResultCode.Success;
        }

        /// <summary>
        /// 为 MES 工具服务提供的异步方法别名 - 更新生产计划
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> UpdateProductionPlanAsync(InsertupdateproductionplanDto dto)
        {
            var result = await UpdateProductionPlan(dto);
            return result.Code == ResultCode.Success;
        }

        /// <summary>
        /// 获取树形下拉列表（根据BOM组成界面优化）
        /// </summary>
        /// <returns>树形结构的下拉列表</returns>
        public async Task<ApiResult<List<TreeNodeDto>>> GetBomTreeDropdownSimple()
        {
            try
            {
                // 查询所有BOM项目
                var allBomItems = await bomItemBase.AsQueryable()
                    .ToListAsync();

                if (!allBomItems.Any())
                {
                    return ApiResult<List<TreeNodeDto>>.Success(new List<TreeNodeDto>(), ResultCode.Success);
                }

                // 查询所有BOM信息
                var bomIds = allBomItems.Select(bi => bi.BomId).Distinct().ToList();
                var allBomInfos = await _db.Queryable<BomInfo>()
                    .Where(bi => bomIds.Contains(bi.Id) && !bi.IsDeleted)
                    .ToListAsync();

                // 查询所有物料信息
                var materialIds = allBomItems.Select(bi => bi.MaterialId).Distinct().Where(id => id != Guid.Empty).ToList();
                var allMaterials = materialIds.Any()
                    ? await _db.Queryable<MaterialEntity>().Where(m => materialIds.Contains(m.Id)).ToListAsync()
                    : new List<MaterialEntity>();

                // 组装导航属性
                foreach (var item in allBomItems)
                {
                    item.Bom = allBomInfos.FirstOrDefault(b => b.Id == item.BomId);
                    item.Material = allMaterials.FirstOrDefault(m => m.Id == item.MaterialId);
                }

                // 按BOM分组构建树形结构
                var result = new List<TreeNodeDto>();
                var sequence = 1;

                foreach (var bomInfo in allBomInfos)
                {
                    // 获取当前BOM的所有项目
                    var bomItems = allBomItems.Where(bi => bi.BomId == bomInfo.Id).ToList();

                    if (bomItems.Any())
                    {
                        // 构建当前BOM的树形结构
                        var bomTree = await BuildCompleteBomTree(bomItems, bomInfo, sequence, 0, 10);
                        result.AddRange(bomTree);
                        sequence += bomTree.Count;
                    }
                }

                return ApiResult<List<TreeNodeDto>>.Success(result, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<List<TreeNodeDto>>.Fail($"获取树形下拉失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 构建完整的BOM树形结构
        /// </summary>
        /// <param name="bomItems">BOM项目列表</param>
        /// <param name="bomInfo">BOM信息</param>
        /// <param name="startSequence">起始序号</param>
        /// <param name="currentDepth">当前深度</param>
        /// <param name="maxDepth">最大深度</param>
        /// <returns>完整的树形结构</returns>
        private async Task<List<TreeNodeDto>> BuildCompleteBomTree(List<BomItem> bomItems, BomInfo bomInfo, int startSequence, int currentDepth, int maxDepth)
        {
            if (currentDepth >= maxDepth)
            {
                Console.WriteLine($"达到最大深度限制: {maxDepth}");
                return new List<TreeNodeDto>();
            }

            var result = new List<TreeNodeDto>();
            var sequence = startSequence;

            // 获取根节点（没有父节点的项目）
            var rootItems = bomItems.Where(item => string.IsNullOrEmpty(item.ParentItemId)).ToList();

            foreach (var item in rootItems)
            {
                var node = await BuildCompleteTreeNode(item, bomItems, sequence++, currentDepth, maxDepth);

                // 为根节点添加BOM信息
                if (string.IsNullOrEmpty(node.BomNumber))
                {
                    node.BomNumber = bomInfo.BomNumber;
                    node.BomVersion = bomInfo.Version;
                }

                result.Add(node);
            }

            return result;
        }

        /// <summary>
        /// 构建完整的树节点
        /// </summary>
        /// <param name="item">BOM项目</param>
        /// <param name="allItems">所有BOM项目</param>
        /// <param name="sequence">序号</param>
        /// <param name="currentDepth">当前深度</param>
        /// <param name="maxDepth">最大深度</param>
        /// <returns>完整的树节点</returns>
        private async Task<TreeNodeDto> BuildCompleteTreeNode(BomItem item, List<BomItem> allItems, int sequence, int currentDepth, int maxDepth)
        {
            // 检查是否有直接子节点
            var hasDirectChildren = allItems.Any(child => child.ParentItemId == item.Id.ToString());

            // 检查物料是否是子BOM（产品类型且有对应的BOM）
            var isSubBom = item.Material?.MaterialType == MaterialTypeEnum.Product;
            var hasSubBomChildren = false;
            List<TreeNodeDto> subBomChildren = new List<TreeNodeDto>();

            if (isSubBom && item.MaterialId != Guid.Empty)
            {
                // 查询该物料是否有对应的BOM
                var subBomInfo = await _db.Queryable<BomInfo>()
                    .Where(bi => bi.ProductId == item.MaterialId)
                    .FirstAsync();

                if (subBomInfo != null)
                {
                    // 查询子BOM的所有项目
                    var subBomItems = await bomItemBase.AsQueryable()
                        .Where(bi => bi.BomId == subBomInfo.Id)
                        .ToListAsync();

                    if (subBomItems.Any())
                    {
                        // 查询子BOM的物料信息
                        var subMaterialIds = subBomItems.Select(bi => bi.MaterialId).Distinct().Where(id => id != Guid.Empty).ToList();
                        var subMaterials = subMaterialIds.Any()
                            ? await _db.Queryable<MaterialEntity>().Where(m => subMaterialIds.Contains(m.Id)).ToListAsync()
                            : new List<MaterialEntity>();

                        // 组装子BOM的导航属性
                        foreach (var subItem in subBomItems)
                        {
                            subItem.Bom = subBomInfo;
                            subItem.Material = subMaterials.FirstOrDefault(m => m.Id == subItem.MaterialId);
                        }

                        // 递归构建子BOM的树形结构
                        subBomChildren = await BuildCompleteBomTree(subBomItems, subBomInfo, 1, currentDepth + 1, maxDepth);
                        hasSubBomChildren = subBomChildren.Any();
                    }
                }
            }

            // 构建直接子节点
            var directChildren = new List<TreeNodeDto>();
            if (hasDirectChildren)
            {
                var childItems = allItems.Where(child => child.ParentItemId == item.Id.ToString()).ToList();
                var childSequence = 1;
                foreach (var childItem in childItems)
                {
                    var childNode = await BuildCompleteTreeNode(childItem, allItems, childSequence++, currentDepth + 1, maxDepth);
                    directChildren.Add(childNode);
                }
            }

            // 合并所有子节点
            var allChildren = new List<TreeNodeDto>();
            allChildren.AddRange(directChildren);
            allChildren.AddRange(subBomChildren);

            var node = new TreeNodeDto
            {
                Id = item.Id,
                Sequence = sequence,
                Name = GetNodeName(item),
                NodeType = GetOptimizedNodeType(item),
                ProductName = GetProductName(item),
                ProductNumber = GetProductNumber(item),
                Specification = GetSpecification(item),
                MaterialName = item.Material?.MaterialName,
                MaterialNumber = item.Material?.MaterialNumber,
                Quantity = item.Quantity,
                Unit = GetUnit(item),
                BomNumber = GetBomNumber(item),
                BomVersion = GetBomVersion(item),
                UsageQuantity = item.Quantity,
                UsageRatio = CalculateUsageRatio(item, allItems),
                InOutType = GetInOutTypeName(item.InOutType),
                IsExpandable = hasDirectChildren || hasSubBomChildren,
                Level = currentDepth,
                ParentId = item.ParentItemId,
                Children = allChildren
            };

            Console.WriteLine($"创建节点: {node.Id}, 名称: {node.Name}, 直接子节点: {directChildren.Count}, 子BOM节点: {subBomChildren.Count}");
            return node;
        }

        /// <summary>
        /// 根据BOM ID获取树形下拉列表（根据BOM组成界面优化）
        /// </summary>
        /// <param name="bomId">BOM ID</param>
        /// <returns>树形结构的下拉列表</returns>
        public async Task<ApiResult<List<BomTreeDto>>> GetBomTreeDropdownByBomId(Guid bomId)
        {
            if (bomId == Guid.Empty)
                return ApiResult<List<BomTreeDto>>.Fail("BOM ID不能为空", ResultCode.Error);

            try
            {
                // 1. 查询BOM基本信息
                var bomInfo = await _db.Queryable<BomInfo>()
                    .Where(b => b.Id == bomId)
                    .FirstAsync();

                if (bomInfo == null)
                    return ApiResult<List<BomTreeDto>>.Fail("未找到指定的BOM信息", ResultCode.Error);

                // 2. 查询BOM项目，关联ProductEntity和MaterialEntity
                var bomItems = await _db.Queryable<BomItem>()
                    .LeftJoin<ProductEntity>((bi, pe) => bi.MaterialId == pe.Id)
                    .LeftJoin<MaterialEntity>((bi, pe, me) => bi.MaterialId == me.Id)
                    .Where((bi, pe, me) => bi.BomId == bomId && !bi.IsDeleted)
                    .Select((bi, pe, me) => new BomTreeStructureDto
                    {
                        Id = bi.Id,
                        BomId = bi.BomId,
                        MaterialId = bi.MaterialId,
                        ParentItemId = bi.ParentItemId,
                        Quantity = bi.Quantity,
                        Unit = bi.Unit,
                        LossRate = bi.LossRate,
                        InOutType = bi.InOutType,
                        Remark = bi.Remark,
                        
                        // BOM信息
                        BomNumber = bomInfo.BomNumber,
                        BomVersion = bomInfo.Version,
                        
                        // 产品信息（来自ProductEntity）
                        ProductName = pe.MaterialName,
                        ProductNumber = pe.MaterialNumber,
                        ProductSpecification = pe.SpecificationModel,
                        //ProductType = pe.MaterialType,
                        
                        // 物料信息（来自MaterialEntity）
                        MaterialName = me.MaterialName,
                        MaterialNumber = me.MaterialNumber,
                        MaterialSpecification = me.SpecificationModel,
                        MaterialType = me.MaterialType,
                        
                        // 计算字段
                        UsageQuantity = bi.Quantity,
                        UsageRatio = "20%", // 这里可以根据实际业务逻辑计算
                        IsExpandable = false, // 稍后设置
                        Level = 0, // 稍后设置
                        Children = new List<BomTreeStructureDto>()
                    })
                    .ToListAsync();

                // 转换为dynamic列表
                var processSteps = bomItems.Cast<dynamic>().ToList();

                // 4. 构建基于工艺路线和工序的BOM树
                var tree = await BuildBomTreeFromProcessSteps(bomInfo, processSteps);

                return ApiResult<List<BomTreeDto>>.Success(tree, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<List<BomTreeDto>>.Fail($"获取BOM树形结构失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 递归构建BOM树，支持子BOM展开
        /// </summary>
        /// <param name="bomId">BOM ID</param>
        /// <param name="currentDepth">当前深度</param>
        /// <param name="maxDepth">最大深度</param>
        /// <returns>树形结构</returns>
        private async Task<List<TreeNodeDto>> BuildBomTreeWithSubBoms(Guid bomId, int currentDepth, int maxDepth)
        {
            if (currentDepth >= maxDepth)
            {
                Console.WriteLine($"达到最大深度限制: {maxDepth}");
                return new List<TreeNodeDto>();
            }

            try
            {
                // 查询指定BOM的所有项目
                var bomItems = await bomItemBase.AsQueryable()
                    .Where(bi => bi.BomId == bomId)
                    .ToListAsync();

                if (!bomItems.Any())
                    return new List<TreeNodeDto>();

                // 查询BomInfo
                var bomInfo = await _db.Queryable<BomInfo>().Where(bi => bi.Id == bomId).FirstAsync();
                if (bomInfo == null)
                    return new List<TreeNodeDto>();

                // 查询物料信息
                var materialIds = bomItems.Select(bi => bi.MaterialId).Distinct().Where(id => id != Guid.Empty).ToList();
                var materials = materialIds.Any()
                    ? await _db.Queryable<MaterialEntity>().Where(m => materialIds.Contains(m.Id)).ToListAsync()
                    : new List<MaterialEntity>();

                // 组装导航属性
                foreach (var item in bomItems)
                {
                    item.Bom = bomInfo;
                    item.Material = materials.FirstOrDefault(m => m.Id == item.MaterialId);
                }

                // 构建当前层级的树形结构
                var result = new List<TreeNodeDto>();
                var sequence = 1;

                // 获取根节点（没有父节点的项目）
                var rootItems = bomItems.Where(item => string.IsNullOrEmpty(item.ParentItemId)).ToList();

                foreach (var item in rootItems)
                {
                    var node = await BuildTreeNodeWithSubBom(item, bomItems, sequence++, currentDepth, maxDepth);
                    result.Add(node);
                }

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"构建BOM树时发生错误: {ex.Message}");
                return new List<TreeNodeDto>();
            }
        }

        /// <summary>
        /// 构建单个树节点，支持子BOM展开
        /// </summary>
        /// <param name="item">BOM项目</param>
        /// <param name="allItems">所有BOM项目</param>
        /// <param name="sequence">序号</param>
        /// <param name="currentDepth">当前深度</param> 
        /// <param name="maxDepth">最大深度</param>
        /// <returns>树节点</returns>
        private async Task<TreeNodeDto> BuildTreeNodeWithSubBom(BomItem item, List<BomItem> allItems, int sequence, int currentDepth, int maxDepth)
        {
            // 检查是否有直接子节点
            var hasDirectChildren = allItems.Any(child => child.ParentItemId == item.Id.ToString());

            // 检查物料是否是子BOM（产品类型且有对应的BOM）
            var isSubBom = item.Material?.MaterialType == MaterialTypeEnum.Product;
            var hasSubBomChildren = false;
            List<TreeNodeDto> subBomChildren = new List<TreeNodeDto>();

            if (isSubBom && item.MaterialId != Guid.Empty)
            {
                // 查询该物料是否有对应的BOM
                var subBomInfo = await _db.Queryable<BomInfo>()
                    .Where(bi => bi.ProductId == item.MaterialId)
                    .FirstAsync();

                if (subBomInfo != null)
                {
                    // 递归查询子BOM的内容
                    subBomChildren = await BuildBomTreeWithSubBoms(subBomInfo.Id, currentDepth + 1, maxDepth);
                    hasSubBomChildren = subBomChildren.Any();
                }
            }

            // 构建直接子节点
            var directChildren = new List<TreeNodeDto>();
            if (hasDirectChildren)
            {
                var childItems = allItems.Where(child => child.ParentItemId == item.Id.ToString()).ToList();
                var childSequence = 1;
                foreach (var childItem in childItems)
                {
                    var childNode = await BuildTreeNodeWithSubBom(childItem, allItems, childSequence++, currentDepth + 1, maxDepth);
                    directChildren.Add(childNode);
                }
            }

            // 合并所有子节点
            var allChildren = new List<TreeNodeDto>();
            allChildren.AddRange(directChildren);
            allChildren.AddRange(subBomChildren);

            var node = new TreeNodeDto
            {
                Id = item.Id,
                Sequence = sequence,
                Name = GetNodeName(item),
                NodeType = GetOptimizedNodeType(item),
                ProductName = GetProductName(item),
                ProductNumber = GetProductNumber(item),
                Specification = GetSpecification(item),
                MaterialName = item.Material?.MaterialName,
                MaterialNumber = item.Material?.MaterialNumber,
                Quantity = item.Quantity,
                Unit = GetUnit(item),
                BomNumber = GetBomNumber(item),
                BomVersion = GetBomVersion(item),
                UsageQuantity = item.Quantity,
                UsageRatio = CalculateUsageRatio(item, allItems),
                InOutType = GetInOutTypeName(item.InOutType),
                IsExpandable = hasDirectChildren || hasSubBomChildren,
                Level = currentDepth,
                ParentId = item.ParentItemId,
                Children = allChildren
            };

            Console.WriteLine($"创建节点: {node.Id}, 名称: {node.Name}, 直接子节点: {directChildren.Count}, 子BOM节点: {subBomChildren.Count}");
            return node;
        }

        /// <summary>
        /// 测试BOM数据结构（调试用）
        /// </summary>
        /// <param name="bomId">BOM ID</param>
        /// <returns>测试结果</returns>
        public async Task<ApiResult<string>> TestBomStructure(Guid bomId)
        {
            try
            {
                // 直接查询数据库
                var allItems = await bomItemBase.AsQueryable()
                    .Where(bi => bi.BomId == bomId)
                    .Select(bi => new { bi.Id, bi.ParentItemId, bi.MaterialId })
                    .ToListAsync();

                var result = new System.Text.StringBuilder();
                result.AppendLine($"=== BOM结构测试 ===");
                result.AppendLine($"BOM ID: {bomId}");
                result.AppendLine($"总项目数: {allItems.Count}");

                // 分析层级结构
                var rootItems = allItems.Where(item => item.ParentItemId == null).ToList();
                var childItems = allItems.Where(item => item.ParentItemId != null).ToList();

                result.AppendLine($"根节点数: {rootItems.Count}");
                result.AppendLine($"子节点数: {childItems.Count}");

                foreach (var root in rootItems)
                {
                    result.AppendLine($"根节点: {root.Id}");
                    var children = childItems.Where(c => c.ParentItemId.toString() == root.Id.toString()).ToList();
                    result.AppendLine($"  直接子节点数: {children.Count}");

                    foreach (var child in children)
                    {
                        result.AppendLine($"    子节点: {child.Id}");
                        var grandChildren = childItems.Where(gc => gc.ParentItemId.toString() == child.Id.toString()).ToList();
                        result.AppendLine($"      孙节点数: {grandChildren.Count}");
                    }
                }

                // 检查孤立节点
                var orphanItems = childItems.Where(item => !allItems.Any(p => p.Id.toString() == item.ParentItemId)).ToList();
                if (orphanItems.Any())
                {
                    result.AppendLine($"警告：发现孤立节点 {orphanItems.Count} 个");
                    foreach (var orphan in orphanItems)
                    {
                        result.AppendLine($"  孤立节点: {orphan.Id}, 父节点: {orphan.ParentItemId}");
                    }
                }

                return ApiResult<string>.Success(result.ToString(), ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<string>.Fail($"测试失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 检查BOM数据是否存在（调试用）
        /// </summary>
        /// <returns>数据检查结果</returns>
        public async Task<ApiResult<string>> CheckBomDataExists()
        {
            try
            {
                var result = new System.Text.StringBuilder();
                result.AppendLine("=== BOM数据检查 ===");

                // 检查BomInfo表
                var bomInfoCount = await _db.Queryable<BomInfo>().CountAsync();
                result.AppendLine($"BomInfo表记录数: {bomInfoCount}");

                if (bomInfoCount > 0)
                {
                    var sampleBomInfos = await _db.Queryable<BomInfo>()
                        .Select(bi => new { bi.Id, bi.BomNumber, bi.ProductName })
                        .Take(5)
                        .ToListAsync();

                    result.AppendLine("示例BOM信息:");
                    foreach (var bom in sampleBomInfos)
                    {
                        result.AppendLine($"  ID: {bom.Id}, 编号: {bom.BomNumber}, 产品: {bom.ProductName}");
                    }
                }

                // 检查BomItem表
                var bomItemCount = await bomItemBase.AsQueryable().CountAsync();
                result.AppendLine($"BomItem表记录数: {bomItemCount}");

                if (bomItemCount > 0)
                {
                    var sampleBomItems = await bomItemBase.AsQueryable()
                        .Select(bi => new { bi.Id, bi.BomId, bi.MaterialId, bi.ParentItemId, bi.Quantity })
                        .Take(5)
                        .ToListAsync();

                    result.AppendLine("示例BOM项目:");
                    foreach (var item in sampleBomItems)
                    {
                        result.AppendLine($"  ID: {item.Id}, BOM ID: {item.BomId}, 物料ID: {item.MaterialId}, 父节点: {item.ParentItemId}, 用量: {item.Quantity}");
                    }
                }

                // 检查MaterialEntity表
                var materialCount = await _db.Queryable<MaterialEntity>().CountAsync();
                result.AppendLine($"MaterialEntity表记录数: {materialCount}");

                if (materialCount > 0)
                {
                    var sampleMaterials = await _db.Queryable<MaterialEntity>()
                        .Select(m => new { m.Id, m.MaterialNumber, m.MaterialName })
                        .Take(5)
                        .ToListAsync();

                    result.AppendLine("示例物料:");
                    foreach (var material in sampleMaterials)
                    {
                        result.AppendLine($"  ID: {material.Id}, 编号: {material.MaterialNumber}, 名称: {material.MaterialName}");
                    }
                }

                return ApiResult<string>.Success(result.ToString(), ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<string>.Fail($"数据检查失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 构建优化的树形结构（根据BOM组成界面）
        /// </summary>
        /// <param name="bomItems">BOM项目列表</param>
        /// <param name="parentId">父节点ID</param>
        /// <param name="startSequence">起始序号</param>
        /// <param name="maxDepth">最大深度限制，防止无限递归</param>
        /// <param name="currentDepth">当前深度</param>
        /// <returns>树形结构</returns>
        private List<TreeNodeDto> BuildOptimizedTree(IEnumerable<BomItem> bomItems, string? parentId, int startSequence, int maxDepth = 10, int currentDepth = 0)
        {
            // 防止无限递归
            if (currentDepth >= maxDepth)
            {
                Console.WriteLine($"达到最大深度限制: {maxDepth}");
                return new List<TreeNodeDto>();
            }

            var sequence = startSequence;
            var result = new List<TreeNodeDto>();

            // 获取当前层级的节点
            var currentLevelItems = bomItems.Where(item => item.ParentItemId == parentId).ToList();

            Console.WriteLine($"BuildOptimizedTree - 深度: {currentDepth}, 父节点ID: {parentId}, 当前层级项目数量: {currentLevelItems.Count}");

            foreach (var item in currentLevelItems)
            {
                // 检查是否有子节点
                var hasChildren = bomItems.Any(child => child.ParentItemId == item.Id.toString());

                Console.WriteLine($"处理项目: {item.Id}, 父节点: {item.ParentItemId}, 有子节点: {hasChildren}");

                // 构建当前节点
                var node = new TreeNodeDto
                {
                    Id = item.Id,
                    Sequence = sequence++,
                    Name = GetNodeName(item),
                    NodeType = GetOptimizedNodeType(item),
                    ProductName = GetProductName(item),
                    ProductNumber = GetProductNumber(item),
                    Specification = GetSpecification(item),
                    MaterialName = item.Material?.MaterialName,
                    MaterialNumber = item.Material?.MaterialNumber,
                    Quantity = item.Quantity,
                    Unit = GetUnit(item),
                    BomNumber = GetBomNumber(item),
                    BomVersion = GetBomVersion(item),
                    UsageQuantity = item.Quantity,
                    UsageRatio = CalculateUsageRatio(item, bomItems),
                    InOutType = GetInOutTypeName(item.InOutType),
                    IsExpandable = hasChildren,
                    Level = currentDepth,
                    ParentId = parentId,
                    Children = hasChildren ? BuildOptimizedTree(bomItems, item.Id.ToString(), 1, maxDepth, currentDepth + 1) : new List<TreeNodeDto>()
                };

                Console.WriteLine($"创建节点: {node.Id}, 子节点数量: {node.Children.Count}");
                result.Add(node);
            }

            Console.WriteLine($"BuildOptimizedTree - 深度: {currentDepth}, 返回节点数量: {result.Count}");
            return result;
        }

        /// <summary>
        /// 构建优化的树形结构（修复版本）
        /// </summary>
        /// <param name="bomItems">BOM项目列表</param>
        /// <param name="parentId">父节点ID</param>
        /// <param name="startSequence">起始序号</param>
        /// <param name="maxDepth">最大深度限制，防止无限递归</param>
        /// <param name="currentDepth">当前深度</param>
        /// <returns>树形结构</returns>
        private List<TreeNodeDto> BuildOptimizedTreeFixed(IEnumerable<BomItem> bomItems, string? parentId, int startSequence, int maxDepth = 10, int currentDepth = 0)
        {
            // 防止无限递归
            if (currentDepth >= maxDepth)
            {
                Console.WriteLine($"达到最大深度限制: {maxDepth}");
                return new List<TreeNodeDto>();
            }

            var sequence = startSequence;
            var result = new List<TreeNodeDto>();

            // 获取当前层级的节点 - 修复字符串比较逻辑
            var currentLevelItems = bomItems.Where(item =>
                (parentId == null && string.IsNullOrEmpty(item.ParentItemId)) ||
                (parentId != null && item.ParentItemId == parentId)
            ).ToList();

            Console.WriteLine($"BuildOptimizedTreeFixed - 深度: {currentDepth}, 父节点ID: {parentId}, 当前层级项目数量: {currentLevelItems.Count}");

            foreach (var item in currentLevelItems)
            {
                // 检查是否有子节点 - 修复字符串比较逻辑
                var hasChildren = bomItems.Any(child => child.ParentItemId == item.Id.ToString());

                Console.WriteLine($"处理项目: {item.Id}, 父节点: {item.ParentItemId}, 有子节点: {hasChildren}");

                // 构建当前节点
                var node = new TreeNodeDto
                {
                    Id = item.Id,
                    Sequence = sequence++,
                    Name = GetNodeName(item),
                    NodeType = GetOptimizedNodeType(item),
                    ProductName = GetProductName(item),
                    ProductNumber = GetProductNumber(item),
                    Specification = GetSpecification(item),
                    MaterialName = item.Material?.MaterialName,
                    MaterialNumber = item.Material?.MaterialNumber,
                    Quantity = item.Quantity,
                    Unit = GetUnit(item),
                    BomNumber = GetBomNumber(item),
                    BomVersion = GetBomVersion(item),
                    UsageQuantity = item.Quantity,
                    UsageRatio = CalculateUsageRatio(item, bomItems),
                    InOutType = GetInOutTypeName(item.InOutType),
                    IsExpandable = hasChildren,
                    Level = currentDepth,
                    ParentId = parentId,
                    Children = hasChildren ? BuildOptimizedTreeFixed(bomItems, item.Id.ToString(), 1, maxDepth, currentDepth + 1) : new List<TreeNodeDto>()
                };

                Console.WriteLine($"创建节点: {node.Id}, 子节点数量: {node.Children.Count}");
                result.Add(node);
            }

            Console.WriteLine($"BuildOptimizedTreeFixed - 深度: {currentDepth}, 返回节点数量: {result.Count}");
            return result;
        }

        /// <summary>
        /// 构建树形结构
        /// </summary>
        /// <param name="bomItems">BOM项目列表</param>
        /// <returns>树形结构</returns>
        private List<TreeNodeDto> BuildTreeStructure(List<BomItem> bomItems)
        {
            var result = new List<TreeNodeDto>();
            var itemDict = new Dictionary<string, TreeNodeDto>();

            // 第一步：创建所有节点
            foreach (var item in bomItems)
            {
                var node = new TreeNodeDto
                {
                    Id = item.Id,
                    Sequence = 0, // 稍后设置
                    Name = GetNodeName(item),
                    NodeType = GetOptimizedNodeType(item),
                    ProductName = GetProductName(item),
                    ProductNumber = GetProductNumber(item),
                    Specification = GetSpecification(item),
                    MaterialName = item.Material?.MaterialName,
                    MaterialNumber = item.Material?.MaterialNumber,
                    Quantity = item.Quantity,
                    Unit = GetUnit(item),
                    BomNumber = GetBomNumber(item),
                    BomVersion = GetBomVersion(item),
                    UsageQuantity = item.Quantity,
                    UsageRatio = CalculateUsageRatio(item, bomItems),
                    InOutType = GetInOutTypeName(item.InOutType),
                    IsExpandable = false, // 稍后设置
                    Level = 0, // 稍后设置
                    ParentId = item.ParentItemId,
                    Children = new List<TreeNodeDto>()
                };

                itemDict[item.Id.ToString()] = node;
            }

            // 第二步：建立父子关系
            foreach (var item in bomItems)
            {
                var node = itemDict[item.Id.ToString()];

                if (item.ParentItemId == "" && itemDict.ContainsKey(item.ParentItemId))
                {
                    // 有父节点，添加到父节点的子节点列表中
                    var parentNode = itemDict[item.ParentItemId];
                    parentNode.Children.Add(node);
                    parentNode.IsExpandable = true;

                    // 设置层级
                    node.Level = parentNode.Level + 1;
                }
                else
                {
                    // 没有父节点，作为根节点
                    result.Add(node);
                    node.Level = 0;
                }
            }

            // 第三步：设置序号和检查可展开性
            var sequence = 1;
            foreach (var rootNode in result)
            {
                SetSequenceAndExpandable(rootNode, ref sequence);
            }

            return result;
        }

        /// <summary>
        /// 设置序号和可展开性
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="sequence">序号</param>
        private void SetSequenceAndExpandable(TreeNodeDto node, ref int sequence)
        {
            node.Sequence = sequence++;

            // 检查是否有子节点
            if (node.Children.Any())
            {
                node.IsExpandable = true;
                foreach (var child in node.Children)
                {
                    SetSequenceAndExpandable(child, ref sequence);
                }
            }
            else
            {
                node.IsExpandable = false;
            }
        }

        /// <summary>
        /// 计算使用比例
        /// </summary>
        /// <param name="item">当前BOM项目</param>
        /// <param name="allItems">所有BOM项目</param>
        /// <returns>使用比例字符串</returns>
        private string CalculateUsageRatio(BomItem item, IEnumerable<BomItem> allItems)
        {
            try
            {
                // 获取同级项目
                var siblings = allItems.Where(x => x.ParentItemId == item.ParentItemId).ToList();

                if (!siblings.Any() || item.Quantity <= 0)
                {
                    return "0%";
                }

                // 计算同级项目的总数量
                var totalQuantity = siblings.Sum(x => x.Quantity);

                if (totalQuantity <= 0)
                {
                    return "0%";
                }

                // 计算当前项目的比例
                var ratio = (item.Quantity / totalQuantity) * 100;
                return $"{ratio:F1}%";
            }
            catch
            {
                return "0%";
            }
        }

        /// <summary>
        /// 获取产品名称
        /// </summary>
        private string? GetProductName(BomItem bomItem)
        {
            if (bomItem.Bom != null && !string.IsNullOrWhiteSpace(bomItem.Bom.ProductName) && bomItem.Bom.ProductName != "string")
            {
                return bomItem.Bom.ProductName;
            }
            return bomItem.Material?.MaterialName;
        }

        /// <summary>
        /// 获取产品编号
        /// </summary>
        private string GetProductNumber(BomItem bomItem)
        {
            if (bomItem.Bom != null && bomItem.MaterialId != null)
            {
                return bomItem.MaterialId.ToString();
            }

            if (bomItem.Material != null && !string.IsNullOrWhiteSpace(bomItem.Material.MaterialNumber))
            {
                return bomItem.Material.MaterialNumber;
            }

            return "WL025";
        }

        /// <summary>
        /// 获取规格型号
        /// </summary>
        private string GetSpecification(BomItem bomItem)
        {
            if (bomItem.Material != null && !string.IsNullOrWhiteSpace(bomItem.Material.SpecificationModel))
            {
                return bomItem.Material.SpecificationModel;
            }
            return "蓝色";
        }

        /// <summary>
        /// 获取单位
        /// </summary>
        private string GetUnit(BomItem bomItem)
        {
            if (!string.IsNullOrWhiteSpace(bomItem.Unit) && bomItem.Unit != "string")
            {
                return bomItem.Unit;
            }
            return "个";
        }

        /// <summary>
        /// 获取BOM编号
        /// </summary>
        private string? GetBomNumber(BomItem bomItem)
        {
            if (bomItem.Bom != null && !string.IsNullOrWhiteSpace(bomItem.Bom.BomNumber) && bomItem.Bom.BomNumber != "string")
            {
                return bomItem.Bom.BomNumber;
            }
            return null;
        }

        /// <summary>
        /// 获取BOM版本
        /// </summary>
        private string GetBomVersion(BomItem bomItem)
        {
            if (bomItem.Bom != null && !string.IsNullOrWhiteSpace(bomItem.Bom.Version) && bomItem.Bom.Version != "string")
            {
                return bomItem.Bom.Version;
            }
            return "1.0";
        }

        /// <summary>
        /// 获取优化的节点类型
        /// </summary>
        /// <param name="bomItem">BOM项目</param>
        /// <returns>节点类型</returns>
        private string GetOptimizedNodeType(BomItem bomItem)
        {
            if (bomItem.Bom != null)
            {
                return "产品";
            }
            else if (bomItem.Material != null)
            {
                return bomItem.Material.MaterialType == MaterialTypeEnum.Product ? "产品" : "物料";
            }
            return "未知";
        }

        /// <summary>
        /// 获取投入产出类型名称
        /// </summary>
        /// <param name="inOutType">投入产出类型枚举</param>
        /// <returns>类型名称</returns>
        private string GetInOutTypeName(MaterialRelationType inOutType)
        {
            return inOutType switch
            {
                MaterialRelationType.Input => "投入",
                MaterialRelationType.Output => "产出",
                MaterialRelationType.ByProduct => "副产品",
                MaterialRelationType.Scrap => "废料",
                MaterialRelationType.Recycled => "可回收",
                _ => "未知"
            };
        }

        /// <summary>
        /// 获取节点名称
        /// 优先显示产品名称，如果没有则显示物料名称
        /// </summary>
        /// <param name="bomItem">BOM项目</param>
        /// <returns>节点名称</returns>
        private string GetNodeName(BomItem bomItem)
        {
            // 优先显示产品名称（来自BomInfo）
            if (bomItem.Bom != null && !string.IsNullOrWhiteSpace(bomItem.Bom.ProductName))
            {
                return $"{bomItem.Bom.ProductName}";
            }

            // 其次显示物料名称（来自MaterialEntity）
            if (bomItem.Material != null && !string.IsNullOrWhiteSpace(bomItem.Material.MaterialName))
            {
                var materialInfo = $"{bomItem.Material.MaterialName}";
                if (!string.IsNullOrWhiteSpace(bomItem.Material.MaterialNumber))
                {
                    materialInfo += $" ({bomItem.Material.MaterialNumber})";
                }
                if (bomItem.Quantity > 0)
                {
                    materialInfo += $" - 用量: {bomItem.Quantity}";
                    if (!string.IsNullOrWhiteSpace(bomItem.Unit))
                    {
                        materialInfo += $" {bomItem.Unit}";
                    }
                }
                return materialInfo;
            }

            // 最后显示BOM编号
            if (bomItem.Bom != null && !string.IsNullOrWhiteSpace(bomItem.Bom.BomNumber))
            {
                return $"BOM: {bomItem.Bom.BomNumber}";
            }

            // 兜底显示
            return $"BOM项目 {bomItem.Id}";
        }


        /// <summary>
        /// 构建基于工艺路线和工序的BOM树
        /// </summary>
        /// <param name="bomInfo">BOM信息</param>
        /// <param name="processSteps">工序列表</param>
        /// <returns>树形结构</returns>
        private async Task<List<TreeNodeDto>> BuildProcessBasedBomTree(BomInfo bomInfo, dynamic processSteps)
        {
            var tree = new List<TreeNodeDto>();
            var sequence = 1;

            // 添加BOM根节点
            var bomRootNode = new TreeNodeDto
            {
                Id = bomInfo.Id,
                Sequence = sequence++,
                Name = $"{bomInfo.ProductName} ({bomInfo.BomNumber})",
                NodeType = "BOM",
                ProductName = bomInfo.ProductName,
                ProductNumber = bomInfo.BomNumber,
                BomNumber = bomInfo.BomNumber,
                BomVersion = bomInfo.Version,
                Children = new List<TreeNodeDto>()
            };

            // 为每个工序创建节点
            foreach (var processStep in processSteps)
            {
                var processNode = new TreeNodeDto
                {
                    Id = processStep.Id,
                    Sequence = sequence++,
                    Name = $"工序: {processStep.ProcessStepName} ({processStep.ProcessStepNumber})",
                    NodeType = "工序",
                    Children = new List<TreeNodeDto>()
                };

                // 如果工序有子BOM，递归添加子BOM的内容
                if (processStep.SubBomId != null && processStep.SubBomId != Guid.Empty)
                {
                    var subBomTree = await GetBomTreeDropdownByBomId(processStep.SubBomId);
                    if (subBomTree.IsSuc && subBomTree.Data != null)
                    {
                        processNode.Children.AddRange(subBomTree.Data);
                    }
                    continue;
                }

                // 查询该工序相关的BOM项目
                var bomItems = await bomItemBase.AsQueryable()
                    .Where(bi => bi.BomId == bomInfo.Id)
                    .ToListAsync();

                // 添加BOM项目到工序节点
                foreach (var bomItem in bomItems)
                {
                    var bomItemNode = new TreeNodeDto
                    {
                        Id = bomItem.Id,
                        Sequence = sequence++,
                        Name = $"BOM项目 {bomItem.Id}",
                        NodeType = "BOM项目",
                        Quantity = bomItem.Quantity,
                        Unit = bomItem.Unit,
                        Children = new List<TreeNodeDto>()
                    };
                    processNode.Children.Add(bomItemNode);
                }

                bomRootNode.Children.Add(processNode);
            }

            tree.Add(bomRootNode);
            return tree;
        }

        /// <summary>
        /// 构建简单的BOM树形结构
        /// </summary>
        /// <param name="bomItems">BOM项目列表</param>
        /// <param name="parentId">父节点ID</param>
        /// <returns>树形结构</returns>
        private List<TreeNodeDto> BuildBomTree(List<BomItem> bomItems, Guid? parentId)
        {
            return bomItems
                .Where(item => item.BomId == parentId)
                .Select(item => new TreeNodeDto
                {
                    Id = item.Id,
                    Name = $"BOM项目 {item.Id}",
                    NodeType = "BOM项目",
                    Quantity = item.Quantity,
                    Unit = item.Unit,
                    Children = BuildBomTree(bomItems, item.Id)
                })
                .ToList();
        }

        /// <summary>
        /// 构建基于工艺路线和工序的BOM树
        /// </summary>
        /// <param name="bomInfo">BOM信息</param>
        /// <param name="processSteps">工序列表</param>
        /// <returns>树形结构</returns>
        private async Task<List<BomTreeDto>> BuildProcessBasedBomTree(BomInfo bomInfo, List<dynamic> processSteps)
        {
            var tree = new List<BomTreeDto>();
            var sequence = 1;

            foreach (var processStep in processSteps)
            {
                var node = new BomTreeDto
                {
                    Sequence = sequence++,
                    ProductName = processStep.ProcessStepName,
                    ProductNumber = processStep.ProcessStepNumber,
                    Specification = "工序",
                    Unit = "个",
                    BomNumber = bomInfo.BomNumber,
                    BomVersion = bomInfo.Version ?? "1.0",
                    UsageQuantity = 1,
                    UsageRatio = "100%",
                    IsExpandable = processStep.SubBomId != null && processStep.SubBomId != Guid.Empty,
                    Children = new List<BomTreeDto>()
                };

                // 如果工序有子BOM，递归添加子BOM的内容
                if (node.IsExpandable)
                {
                    var subBomChildren = await GetSubBomTreeNodes(processStep.SubBomId);
                    node.Children.AddRange(subBomChildren);
                }

                tree.Add(node);
            }

            return tree;
        }

        /// <summary>
        /// 获取子BOM的树形节点（新的工具方法）
        /// </summary>
        /// <param name="subBomId">子BOM ID</param>
        /// <returns>子BOM的树形节点列表</returns>
        private async Task<List<BomTreeDto>> GetSubBomTreeNodes(Guid subBomId)
        {
            try
            {
                // 查询子BOM信息
                var subBomInfo = await _db.Queryable<BomInfo>()
                    .Where(b => b.Id == subBomId)
                    .FirstAsync();

                if (subBomInfo == null)
                    return new List<BomTreeDto>();

                // 查询子BOM的工艺路线
                var subProcessRoute = await _db.Queryable<ProcessRouteEntity>()
                    .Where(pr => pr.Id == subBomInfo.ProcessRouteId)
                    .FirstAsync();

                if (subProcessRoute == null)
                    return new List<BomTreeDto>();

                // 查询子BOM的工序
                var subProcessStepsQuery = await _db.Queryable<ProcessStep>()
                    .LeftJoin<ProcessRouteStep>((ps, prs) => ps.Id == prs.ProcessStepId)
                    .Where((ps, prs) => prs.ProcessRouteId == subProcessRoute.Id)
                    .OrderBy((ps, prs) => prs.StepOrder)
                    .Select((ps, prs) => new
                    {
                        ps.Id,
                        ps.ProcessStepName,
                        ps.ProcessStepNumber,
                        ps.SubBomId,
                        prs.StepOrder
                    })
                    .ToListAsync();

                // 转换为dynamic列表
                var subProcessSteps = subProcessStepsQuery.Cast<dynamic>().ToList();

                // 递归构建子BOM的树形结构
                return await BuildBomTreeFromProcessSteps(subBomInfo, subProcessSteps);
            }
            catch (Exception)
            {
                return new List<BomTreeDto>();
            }
        }


        /// <summary>
        /// 从工序步骤构建BOM树形结构（新的工具方法）
        /// </summary>
        /// <param name="bomInfo">BOM信息</param>
        /// <param name="processSteps">工序步骤列表</param>
        /// <returns>树形结构</returns>
        private async Task<List<BomTreeDto>> BuildBomTreeFromProcessSteps(BomInfo bomInfo, List<dynamic> processSteps)
        {
            var tree = new List<BomTreeDto>();
            var sequence = 1;

            foreach (var processStep in processSteps)
            {
                var node = new BomTreeDto
                {
                    Sequence = sequence++,
                    ProductName = processStep.ProcessStepName,
                    ProductNumber = processStep.ProcessStepNumber,
                    Specification = "工序",
                    Unit = "个",
                    BomNumber = bomInfo.BomNumber,
                    BomVersion = bomInfo.Version ?? "1.0",
                    UsageQuantity = 1,
                    UsageRatio = "100%",
                    IsExpandable = processStep.SubBomId != null && processStep.SubBomId != Guid.Empty,
                    Children = new List<BomTreeDto>()
                };

                // 如果工序有子BOM，递归添加子BOM的内容
                if (node.IsExpandable)
                {
                    var subBomChildren = await GetSubBomTreeNodes(processStep.SubBomId);
                    node.Children.AddRange(subBomChildren);
                }

                tree.Add(node);
            }

            return tree;
        }

        /// <summary>
        /// 获取BOM树形结构（关联BomInfo、ProductEntity、MaterialEntity表）
        /// </summary>
        /// <param name="bomId">BOM ID</param>
        /// <returns>BOM树形结构</returns>
        public async Task<ApiResult<List<BomTreeStructureDto>>> GetBomTreeStructure(Guid bomId)
        {
            if (bomId == Guid.Empty)
                return ApiResult<List<BomTreeStructureDto>>.Fail("BOM ID不能为空", ResultCode.Error);

            try
            {
                // 1. 查询BOM基本信息
                var bomInfo = await _db.Queryable<BomInfo>()
                    .Where(b => b.Id == bomId && !b.IsDeleted)
                    .FirstAsync();

                if (bomInfo == null)
                    return ApiResult<List<BomTreeStructureDto>>.Fail("未找到指定的BOM信息", ResultCode.Error);

                // 2. 查询BOM项目，包括当前BOM的项目和那些parentitemid指向当前BOM的项目
                var bomItems = await _db.Queryable<BomItem>()
                    .Where(bi => (bi.BomId == bomId || bi.ParentItemId == bomId.ToString()) && !bi.IsDeleted)
                    .ToListAsync();

                if (!bomItems.Any())
                {
                    return ApiResult<List<BomTreeStructureDto>>.Success(new List<BomTreeStructureDto>(), ResultCode.Success);
                }

                // 3. 获取所有相关的物料ID
                var materialIds = bomItems.Select(bi => bi.MaterialId).Distinct().Where(id => id != Guid.Empty).ToList();

                // 4. 查询产品信息
                var products = materialIds.Any() 
                    ? await _db.Queryable<ProductEntity>().Where(p => materialIds.Contains(p.Id)).ToListAsync()
                    : new List<ProductEntity>();

                // 5. 查询物料信息
                var materials = materialIds.Any()
                    ? await _db.Queryable<MaterialEntity>().Where(m => materialIds.Contains(m.Id)).ToListAsync()
                    : new List<MaterialEntity>();

                // 6. 构建BomTreeStructureDto列表
                var bomTreeItems = new List<BomTreeStructureDto>();
                foreach (var item in bomItems)
                {
                    var product = products.FirstOrDefault(p => p.Id == item.MaterialId);
                    var material = materials.FirstOrDefault(m => m.Id == item.MaterialId);

                    var bomTreeItem = new BomTreeStructureDto
                    {
                        Id = item.Id,
                        BomId = item.BomId,
                        MaterialId = item.MaterialId,
                        ParentItemId = item.ParentItemId,
                        Quantity = item.Quantity,
                        Unit = item.Unit,
                        LossRate = item.LossRate,
                        InOutType = item.InOutType,
                        Remark = item.Remark,
                        
                        // BOM信息
                        BomNumber = bomInfo.BomNumber,
                        BomVersion = bomInfo.Version,
                        
                        // 产品信息（来自ProductEntity）
                        ProductName = product?.MaterialName,
                        ProductNumber = product?.MaterialNumber,
                        ProductSpecification = product?.SpecificationModel,
                        //ProductType = product?.MaterialType,
                        
                        // 物料信息（来自MaterialEntity）
                        MaterialName = material?.MaterialName,
                        MaterialNumber = material?.MaterialNumber,
                        MaterialSpecification = material?.SpecificationModel,
                        MaterialType = material?.MaterialType,
                        
                        // 计算字段
                        UsageQuantity = item.Quantity,
                        UsageRatio = "20%", // 这里可以根据实际业务逻辑计算
                        IsExpandable = false, // 稍后设置
                        Level = 0, // 稍后设置
                        Children = new List<BomTreeStructureDto>()
                    };

                    bomTreeItems.Add(bomTreeItem);
                }

                // 调试信息：打印BOM项目信息
                Console.WriteLine($"=== BOM树形结构调试信息 ===");
                Console.WriteLine($"BOM ID: {bomId}");
                Console.WriteLine($"总BOM项目数: {bomItems.Count}");
                Console.WriteLine($"产品数: {products.Count}");
                Console.WriteLine($"物料数: {materials.Count}");
                
                foreach (var item in bomItems)
                {
                    Console.WriteLine($"BOM项目: ID={item.Id}, BomId={item.BomId}, ParentItemId={item.ParentItemId}, MaterialId={item.MaterialId}");
                }
                
                Console.WriteLine($"构建的BomTreeItems数: {bomTreeItems.Count}");
                foreach (var item in bomTreeItems)
                {
                    Console.WriteLine($"树形项目: ID={item.Id}, BomId={item.BomId}, ParentItemId={item.ParentItemId}, DisplayName={item.DisplayName}");
                }

                // 7. 构建树形结构
                var tree = BuildBomTreeStructure(bomTreeItems);

                // 8. 设置序号
                SetSequenceNumbers(tree);

                return ApiResult<List<BomTreeStructureDto>>.Success(tree, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<List<BomTreeStructureDto>>.Fail($"获取BOM树形结构失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 构建BOM树形结构
        /// </summary>
        /// <param name="bomItems">BOM项目列表</param>
        /// <returns>树形结构</returns>
        private List<BomTreeStructureDto> BuildBomTreeStructure(List<BomTreeStructureDto> bomItems)
        {
            var result = new List<BomTreeStructureDto>();
            var itemDict = new Dictionary<string, BomTreeStructureDto>();

            // 第一步：创建所有节点
            foreach (var item in bomItems)
            {
                // 设置显示名称（优先显示产品名称，其次显示物料名称）
                item.DisplayName = !string.IsNullOrEmpty(item.ProductName) ? item.ProductName : item.MaterialName;
                
                // 设置产品编号（优先使用产品编号，其次使用物料编号）
                item.DisplayProductNumber = !string.IsNullOrEmpty(item.ProductNumber) ? item.ProductNumber : item.MaterialNumber;
                
                // 设置规格型号（优先使用产品规格，其次使用物料规格）
                item.DisplaySpecification = !string.IsNullOrEmpty(item.ProductSpecification) ? item.ProductSpecification : item.MaterialSpecification;

                // 使用Id作为字典的键
                itemDict[item.Id.ToString()] = item;
            }

            // 第二步：建立父子关系
            Console.WriteLine("=== 建立父子关系 ===");
            foreach (var item in bomItems)
            {
                var node = itemDict[item.Id.ToString()];
                Console.WriteLine($"处理节点: ID={item.Id}, BomId={item.BomId}, ParentItemId={item.ParentItemId}");

                // 检查是否有父节点
                if (!string.IsNullOrEmpty(item.ParentItemId))
                {
                    Console.WriteLine($"  节点 {item.Id} 有父节点: {item.ParentItemId}");
                    
                    // 尝试查找父节点
                    // 首先尝试查找ID匹配的父节点
                    if (itemDict.ContainsKey(item.ParentItemId))
                    {
                        // 如果parentitemid是当前BOM内某个项目的ID
                        var parentNode = itemDict[item.ParentItemId];
                        parentNode.Children.Add(node);
                        parentNode.IsExpandable = true;
                        node.Level = parentNode.Level + 1;
                        Console.WriteLine($"  成功找到父节点 {item.ParentItemId}，添加到子节点列表");
                    }
                    else
                    {
                        // 如果找不到ID匹配的父节点，尝试查找BomId匹配的父节点
                        var parentByBomId = bomItems.FirstOrDefault(p => p.BomId.ToString() == item.ParentItemId);
                        if (parentByBomId != null && itemDict.ContainsKey(parentByBomId.Id.ToString()))
                        {
                            var parentNode = itemDict[parentByBomId.Id.ToString()];
                            parentNode.Children.Add(node);
                            parentNode.IsExpandable = true;
                            node.Level = parentNode.Level + 1;
                            Console.WriteLine($"  通过BomId找到父节点 {parentByBomId.Id}，添加到子节点列表");
                        }
                        else
                        {
                            // 如果找不到父节点，作为根节点处理
                            result.Add(node);
                            node.Level = 0;
                            Console.WriteLine($"  未找到父节点 {item.ParentItemId}，作为根节点处理");
                        }
                    }
                }
                else
                {
                    // 没有父节点，作为根节点
                    result.Add(node);
                    node.Level = 0;
                    Console.WriteLine($"  节点 {item.Id} 没有父节点，作为根节点");
                }
            }

            // 第三步：递归设置子节点的层级和可展开性
            foreach (var rootNode in result)
            {
                SetNodeProperties(rootNode);
            }

            return result;
        }

        /// <summary>
        /// 设置节点属性（层级和可展开性）
        /// </summary>
        /// <param name="node">节点</param>
        private void SetNodeProperties(BomTreeStructureDto node)
        {
            // 检查是否有子节点
            if (node.Children.Any())
            {
                node.IsExpandable = true;
                foreach (var child in node.Children)
                {
                    child.Level = node.Level + 1;
                    SetNodeProperties(child);
                }
            }
            else
            {
                node.IsExpandable = false;
            }
        }

        /// <summary>
        /// 设置序号
        /// </summary>
        /// <param name="nodes">节点列表</param>
        private void SetSequenceNumbers(List<BomTreeStructureDto> nodes)
        {
            var sequence = 1;
            foreach (var node in nodes)
            {
                SetNodeSequence(node, ref sequence);
            }
        }

        /// <summary>
        /// 设置节点序号（递归）
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="sequence">序号</param>
        private void SetNodeSequence(BomTreeStructureDto node, ref int sequence)
        {
            node.Sequence = sequence++;

            foreach (var child in node.Children)
            {
                SetNodeSequence(child, ref sequence);
            }
        }
    }
}

